package com.avsdk;


import android.util.Log;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
/*
 * audio绫诲澶栨彁渚涗袱涓猵ublic鍑芥暟锛屽垎鍒槸锛�
 * 褰曞埗澹伴煶鐨剅ecordAudio()
 * 鎾斁澹伴煶鐨凱layAudio()
 */



import android.os.Environment;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;







public class audioRecordPlay{

	//涓撶敤Log鏍囧織00
	private String TAG="audioRecordPlay";
	//闊抽閲囨牱鐜�
	private final static int SampleRates=8000;
	//姣忓抚閲囬泦鐨勯煶棰戞椂闂撮暱搴�
	private final static int timePerFrame=20;
	//姣忎竴涓彂閫佸寘鐨勫抚棰戞暟
	private final static int  framePerPackage=4;
	//姣忎竴甯у寘鍚殑瀛楄妭鏁�
	private int bytesPerFrame=(timePerFrame*SampleRates*2)/1000;
	//姣忎竴鍖呭寘鍚殑瀛楄妭鏁�
	private int bytesPerPackage=bytesPerFrame*framePerPackage;
	//鎺ユ敹閲囬泦澹伴煶鏁版嵁鐨勫彂閫佺紦瀛�
	private final byte[] audioBufferRecord;
	//鎺ユ敹缃戠粶绔彂閫佹潵闊抽鍖呯殑缂撳瓨
	private byte[] audioBufferPlay;
	//鍒ゆ柇褰撳墠鏄惁姝ｅ湪璇�
	public boolean isRecording;
	//鍒ゆ柇褰撳墠鏄惁姝ｅ湪璇�
	public boolean isPlaying;



	public boolean capfinish = true;
	public boolean playfinish = true;	
	AVCapCallBack mAVCapCallBack = null;


	public audioRecordPlay()
	{

		isRecording=false;
		isPlaying=false;
		audioBufferRecord= new byte[bytesPerPackage];
//		audioBufferPlay=new byte[bytesPerPackage];



	}

	public void SetCallback(AVCapCallBack avcb)
	{
		mAVCapCallBack = avcb;
	}





	public void recordAudio() {
		//璁惧畾閲囬泦鐘舵�佹爣蹇�
		isRecording=true;
		capfinish = false;



		//璁剧疆闊抽閲囬泦鍑芥暟鎵�鍦ㄧ嚎绋嬬殑浼樺厛绾�
		android.os.Process.setThreadPriority(
				android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
		//鑾峰彇鍚堥�傜殑闊抽閲囬泦鐨勫師濮嬬紦鍐插尯
		int recBufSize =
				AudioRecord.getMinBufferSize(SampleRates,
						AudioFormat.CHANNEL_CONFIGURATION_MONO,
						AudioFormat.ENCODING_PCM_16BIT);
		//鍒涘缓闊抽閲囬泦瀵硅薄
		AudioRecord audioRecorder=
				new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SampleRates,
						AudioFormat.CHANNEL_CONFIGURATION_MONO,
						AudioFormat.ENCODING_PCM_16BIT,
						recBufSize);


		//寮�濮婣udioRecord褰曞埗澹伴煶
		try {
			audioRecorder.startRecording();
		} catch (IllegalStateException e) {
			e.printStackTrace();
		}
		int bufferSize = 160;
		byte[] buffer = new byte[bufferSize];



		int pcmrecordpos = 0;
		//寰幆褰曞埗
		while(isRecording){
			//灏嗗綍闊冲彂閫佺紦瀛樻竻绌�
//			Arrays.fill(audioBufferRecord, (byte) 0);
			//姣忎竴涓寘瀹為檯鏀跺埌鐨勫瓧鑺傛暟

			int actualBytesPerFrame=0;
			int ret = 0;
			//灏嗗寘涓殑姣忎竴甯х殑鍘熷瑙嗛鏁版嵁瀛樺叆鍙戦�佺紦瀛樹箣涓�
			int i = 0;

			while (actualBytesPerFrame < bytesPerPackage) {
				//鏄痳ead杩樻槸write锛屼互鍐呭瓨涓轰腑蹇冿紝浠庡唴瀛樺嚭锛屾槸鍐欙紱杩涘叆鍐呭瓨锛屾槸璇�
				if(isRecording != true)
				{
					break;
				}
				ret = audioRecorder.read(buffer, 0, bufferSize);
				if(ret <= 0)
				{
					try {
						Thread.sleep(10);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					continue;
				}



				System.arraycopy(buffer, 0, audioBufferRecord, actualBytesPerFrame, ret);

				actualBytesPerFrame = actualBytesPerFrame + ret;
//				i++;
//				Log.d("send", "閲囬泦1甯ч煶棰�");
			}
			if(isRecording != true)
			{
				break;
			}


			//灏嗕竴涓寘涓�8甯х殑闊抽鏁版嵁鍐欏叆锛屽啓鍏ユ暟鎹殑鎬婚暱搴﹀湪actualBytesPerFrame涓互鍖呬负鍗曚綅璁＄畻鍑烘潵
			if((isRecording)&&(mAVCapCallBack != null))
				mAVCapCallBack.OnAudioCallBack(audioBufferRecord, actualBytesPerFrame);
//			Log.d("send", "褰撳墠鍖呭彂閫佷簡"+actualBytesPerFrame+"瀛楄妭鐨勯煶棰戞暟鎹�");

		}
		//褰撲互涓妛hile寰幆缁撴潫鏃讹紝琛ㄧず闊抽閲囬泦缁撴潫锛屽仠姝㈤噰闆嗐�侀噴鏀惧綍闊宠祫婧愩�佺疆绌哄綍闊冲璞�
		try {


			audioRecorder.stop();
			audioRecorder.release();
			//灏哸udioRecorder鎸囧悜鐨勫璞¤鍨冨溇鍥炴敹
			audioRecorder=null;

		} catch (IllegalStateException e) {
			e.printStackTrace();
		}

		capfinish = true;
	}

	private Lock lock = new ReentrantLock();
	ArrayList<byte[]> playlist = new ArrayList<byte[]>();
	public void AddPlayBuffer(byte[] playbuffer, int len)
	{
		lock.lock();		
		byte[] buffer = new byte[len];
		System.arraycopy(playbuffer, 0, buffer,0,len);
		playlist.add(buffer);
		lock.unlock();
	}
	

	public void OnPlay() {
		Log.d(TAG, "wwwwwwwwwwwwwwwwwwwwwww");

		playfinish = false;

		//璁惧畾闊抽鎾斁鏍囧織
		isPlaying=true;
		// set high thread priority
		android.os.Process.setThreadPriority(
				android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
		final int playBufSize = AudioTrack.getMinBufferSize(SampleRates,AudioFormat.CHANNEL_CONFIGURATION_MONO,AudioFormat.ENCODING_PCM_16BIT);
		AudioTrack audioPlay;
//		audioPlay =new AudioTrack(AudioManager.STREAM_MUSIC, SampleRates,
		audioPlay =new AudioTrack(AudioManager.STREAM_VOICE_CALL, SampleRates,
				AudioFormat.CHANNEL_CONFIGURATION_MONO,
				AudioFormat.ENCODING_PCM_16BIT,
				playBufSize, AudioTrack.MODE_STREAM);


//		audioPlay.getMaxVolume();



		Log.d(TAG, "playBufSize:"+playBufSize);

		//寮�濮嬫挱鏀惧鏂圭殑闊抽娴�


		try {
			audioPlay.play();

		} catch (IllegalStateException e) {
			e.printStackTrace();
			Log.d(TAG, "play.play() error");
		}
		Log.d(TAG, "play start");
		//寰幆鎺ユ敹鏁版嵁


		int bufferSize = 160;
		byte[] buffer = new byte[bufferSize];


		while(true){


			//灏嗗綍闊冲彂閫佺紦瀛樻竻绌�
			int actualBytesPerFrame=0;


			lock.lock();
			if(playlist.size() > 0)
			{
				try {
	
	
					audioBufferPlay = playlist.get(0);
					playlist.remove(0);
					actualBytesPerFrame = audioBufferPlay.length;
				}finally {
					lock.unlock();// 閲婃斁閿�
				}
												
			}else{
				lock.unlock();
			}



			

			if(actualBytesPerFrame >0)
			{

				Log.d("TAG", "read audio len:"+actualBytesPerFrame);

				int pos = 0;
				while(actualBytesPerFrame >= bufferSize)
				{
					System.arraycopy(audioBufferPlay, pos, buffer, 0, bufferSize);
					int ret = audioPlay.write(buffer, 0, bufferSize);
					if(ret > 0)
					{

						actualBytesPerFrame = actualBytesPerFrame - bufferSize;
						pos = pos + bufferSize;
					}else{
						if(isPlaying == false)
							break;
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}

				}


			}else{



				try {
//					Log.d(TAG, "娌℃湁鎺ユ敹鍒伴煶棰戞暟鎹�");
					Thread.sleep(40);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(isPlaying == false)
				break;
		}


		Log.d(TAG, "play over");
		try {
			audioPlay.stop();
			audioPlay.release();
			//灏哸udioPlay鎸囧悜鐨勫璞¤鍨冨溇鍥炴敹
			audioPlay=null;
			Log.d(TAG, "audioplay has been stopped");
		} catch (IllegalStateException e) {
			e.printStackTrace();
		}
		playfinish = true;
	}
}
